package com.jyh.blog.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jyh.blog.dao.CommentDao;
import com.jyh.blog.dao.TalkDao;
import com.jyh.blog.dto.CommentCountDTO;
import com.jyh.blog.dto.TalkBackDTO;
import com.jyh.blog.dto.TalkDTO;
import com.jyh.blog.entity.Talk;
import com.jyh.blog.exception.MyException;
import com.jyh.blog.service.RedisService;
import com.jyh.blog.service.TalkService;
import com.jyh.blog.utils.*;
import com.jyh.blog.vo.ConditionVO;
import com.jyh.blog.vo.PageResult;
import com.jyh.blog.vo.TalkVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.jyh.blog.constant.RedisPrefixConst.TALK_LIKE_COUNT;
import static com.jyh.blog.constant.RedisPrefixConst.TALK_USER_LIKE;
import static com.jyh.blog.enums.ArticleStatusEnum.PUBLIC;

/**
 * (Talk)表服务实现类
 *
 * @author jyh
 * @since 2023-02-13 16:26:44
 */
@Service("talkService")
public class TalkServiceImpl extends ServiceImpl<TalkDao, Talk> implements TalkService {
    @Autowired
    private TalkDao talkDao;
    @Autowired
    private RedisService redisService;
    @Autowired
    private CommentDao commentDao;

    @Override
    public PageResult<TalkBackDTO> talkBackList(ConditionVO conditionVO) {
        //查询数量
        Integer count = talkDao.selectCount(new LambdaQueryWrapper<Talk>()
                .eq(!ObjectUtils.isEmpty(conditionVO.getStatus()), Talk::getStatus, conditionVO.getStatus()));
        if (count == 0) {
            return new PageResult<>();
        }
        List<TalkBackDTO> talkBackDTOS = talkDao.talkBackDTOList(PageUtils.getLimitCurrent(), PageUtils.getSize(), conditionVO.getStatus());
        //转换图片格式
        talkBackDTOS.forEach(item -> {
                    if (!ObjectUtils.isEmpty(item.getImages())) {
                        item.setImgList(CommonUtils.castList(JSON.parseObject(item.getImages(), List.class), String.class));
                    }
                }
        );
        return new PageResult<>(talkBackDTOS, count);
    }

    @Override
    public TalkDTO getTalkById(String talkId) {
        TalkDTO talkDTO= talkDao.getTalkById(talkId);
        if(Objects.isNull(talkDTO)){
            throw  new MyException("说说不存在");
        }
        talkDTO.setLikeCount((Integer)redisService.hGet(TALK_LIKE_COUNT,talkId));
        //封装图片
        if(Objects.nonNull(talkDTO.getImages())){
            talkDTO.setImgList(CommonUtils.castList(JSON.parseObject(talkDTO.getImages(),List.class),String.class));
        }
        return talkDTO;
    }

    @Override
    public void saveOrUpdateTalk(TalkVO talkVO) {
        Talk talk = BeanCopyUtils.copyObject(talkVO, Talk.class);
        //user_info表的id作为talk表的user_id
        talk.setUserId(UserUtils.getLoginUser().getUserInfoId());
        this.saveOrUpdate(talk);
    }


    @Override
    public void deleteTalk(String talkId) {
        this.removeById(talkId);
    }

    @Override
    public TalkBackDTO getTalkBackById(String talkId) {
        TalkBackDTO talkBackDTO = talkDao.getTalkBackById(talkId);
        if(Objects.nonNull(talkBackDTO.getImages())){
            //转换图片格式
            talkBackDTO.setImgList(CommonUtils.castList(JSON.parseObject(talkBackDTO.getImages(), List.class), String.class));
        }
        return talkBackDTO;
    }

    //最新10条说说
    @Override
    public List<String> talkHomeList() {
        return this.list(new LambdaQueryWrapper<Talk>().eq(Talk::getStatus, PUBLIC.getStatus())
                .orderByDesc(Talk::getIsTop)
                .orderByDesc(Talk::getId)
                .last("limit 10")
        )
                .stream()
                //过滤内容
                .map(item -> item.getContent().length() > 200 ? HTMLUtils.deleteHMTLTag(item.getContent().substring(0, 200)): HTMLUtils.deleteHMTLTag(item.getContent()))
                .collect(Collectors.toList());
    }
    //逻辑同文章点赞
    @Override
    public void talkLike(String talkId) {
        String key=TALK_USER_LIKE+UserUtils.getLoginUser().getUserInfoId();
        if(redisService.sIsMember(key,talkId)){
            redisService.sRemove(key,talkId);
            redisService.hDecr(TALK_LIKE_COUNT,talkId,1L);
        }else{
            redisService.sAdd(key,talkId);
            redisService.hIncr(TALK_LIKE_COUNT,talkId,1L);
        }
    }

    @Override
    public PageResult<TalkDTO> talkList() {
        //说说总数
        int count = this.count(new LambdaQueryWrapper<Talk>().eq(Talk::getStatus, PUBLIC.getStatus()));
        if(count==0){
            return new PageResult<>();
        }
        //分页查询说说
        List<TalkDTO> talkDTOList= talkDao.pageList(PageUtils.getLimitCurrent(),PageUtils.getSize());
        if(CollectionUtils.isEmpty(talkDTOList)){
            return new PageResult<>();
        }
        //提取说说id
        List<String> idList = talkDTOList.stream().map(TalkDTO::getId).collect(Collectors.toList());
        //根据说说id查询评论，将结果list转为map
        Map<String, Integer> replyCountMap = commentDao.replyCountListByTopicId(idList).stream()
                .collect(Collectors.toMap(CommentCountDTO::getId, CommentCountDTO::getCommentCount));
        //查询点赞量
        Map<String, Object> likeCountMap = redisService.hGetAll(TALK_LIKE_COUNT);
        //封装
        talkDTOList.forEach(item->{
            item.setLikeCount((Integer) likeCountMap.get(item.getId()));
            item.setCommentCount(replyCountMap.get(item.getId()));
            if(Objects.nonNull(item.getImages())){
                item.setImgList(CommonUtils.castList(JSON.parseObject(item.getImages(),List.class),String.class));
            }
        });
        return new PageResult<>(talkDTOList,count);
    }
}

